﻿using System;
using System.Data;
using System.Linq;
using System.Windows.Forms;
using Microsoft.SqlServer.Dts.Runtime;
using System.Xml;
using SSISComponents.ReportGenerator.ReportExecution2005;

namespace SSISComponents.ReportGenerator
{
    public partial class ReportGeneratorUI : Form
    {
       
        #region Private Variables
        
        private TaskHost _taskHost;
        private Connections _connections;
        private RenderExtensions _renderExtensions;
        
        private string _Reportname = null;
        private string _Recordset = null;
        private string _Filename = null;
        private string _Datasetname = null;
        private string _ReportServer = null;
        private string _ReportType = "Dataset Report";
        private string _Password = null;
        private string _Username = null;
        private string _PrefixFilename = null;
        private Boolean _WindowsAuthorization = false;
        private Boolean _Prefix = true;
        private Boolean _DebugMode = false;
        private DataTable _Variable;
        private DataTable _Reportparameter = null;
        private string _Param = null;
        private Boolean _Snapshot = false;

        #endregion

        #region Constructor

        /// <summary>
        /// 
        /// </summary>
        /// <param name="taskHost"></param>
        /// <param name="connections"></param>
        public ReportGeneratorUI(TaskHost taskHost, Connections connections)
        {
            InitializeComponent();
            this._taskHost = taskHost;
            this._connections = connections;
            this._renderExtensions = new RenderExtensions();
        }
        #endregion

        #region Form Event Handlers
       
        /// <summary>
        /// set all task properties to local vaariables
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ReportGeneratorUI_Load(object sender, EventArgs e)
        {
            //dgvReportParameter.VirtualMode = true;
            BuildDataTable();

            object _ReportnameObjectValue = this._taskHost.Properties["Reportname"].GetValue(this._taskHost);
            object _RecordsetObjectValue = this._taskHost.Properties["Recordset"].GetValue(this._taskHost);
            object _FilenameObjectValue = this._taskHost.Properties["Filename"].GetValue(this._taskHost);
            object _DatasetnameObjectValue = this._taskHost.Properties["Datasetname"].GetValue(this._taskHost);
            object _PrefixObjectValue = this._taskHost.Properties["Prefix"].GetValue(this._taskHost);
            object _DebugModeObjectValue = this._taskHost.Properties["DebugMode"].GetValue(this._taskHost);
            object _ReportServerObjectValue = this._taskHost.Properties["ReportServer"].GetValue(this._taskHost);
            object _ReportTypeObjectValue = this._taskHost.Properties["ReportType"].GetValue(this._taskHost);
            object _UsernameObjectValue = this._taskHost.Properties["Username"].GetValue(this._taskHost);
            object _PasswordObjectValue = this._taskHost.Properties["Password"].GetValue(this._taskHost);
            object _WindowsAuthorizationObjectValue = this._taskHost.Properties["WindowsAuthorization"].GetValue(this._taskHost);
            object _PrefixFilenameObjectValue = this._taskHost.Properties["PrefixFilename"].GetValue(this._taskHost);
            object _ReportparameterObjectValue = this._taskHost.Properties["Reportparameter"].GetValue(this._taskHost);
            object _SnapshotObjectValue = this._taskHost.Properties["Snapshot"].GetValue(this._taskHost);

            if (_ReportnameObjectValue != null)
            {
                _Reportname = _ReportnameObjectValue.ToString();
            }

            if (_DatasetnameObjectValue != null)
            {
                _Datasetname = _DatasetnameObjectValue.ToString();
            }

            if (_RecordsetObjectValue != null)
            {
                _Recordset = _RecordsetObjectValue.ToString();
            }

            if (_FilenameObjectValue != null)
            {
                _Filename = _FilenameObjectValue.ToString();
            }

            if (_WindowsAuthorizationObjectValue != null)
            {
                _WindowsAuthorization = (bool)_WindowsAuthorizationObjectValue;
            }

            if (_PrefixObjectValue != null)
            {
                _Prefix = (bool)_PrefixObjectValue;
            }

            if (_DebugModeObjectValue != null)
            {
                _DebugMode = (bool)_DebugModeObjectValue;
            }

            if (_SnapshotObjectValue != null)
            {
                _Snapshot = (bool)_SnapshotObjectValue;
            }

            if (_ReportServerObjectValue != null)
            {
                _ReportServer = _ReportServerObjectValue.ToString();
            }

            if (_ReportTypeObjectValue != null)
            {
                _ReportType = _ReportTypeObjectValue.ToString();
            }

            if (_UsernameObjectValue != null)
            {
                _Username = _UsernameObjectValue.ToString();
            }

            if (_PasswordObjectValue != null)
            {
                _Password = _PasswordObjectValue.ToString();
            }

            if (_PrefixFilenameObjectValue != null)
            {
                _PrefixFilename = _PrefixFilenameObjectValue.ToString();
            }

            if (_ReportparameterObjectValue != null)
            {
                _Reportparameter = (DataTable)ReportGenerator.DeserializeObject(_ReportparameterObjectValue.ToString());
            }

            this.txtLocation.Text = _Filename;
            this.txtReports.Text = _Reportname;
            this.txtReportServer.Text = _ReportServer;
            if (String.IsNullOrEmpty(this.txtReportServer.Text)) this.txtReportServer.Text = @"http://localhost/reportserver";
            this.cbReportType.Text = _ReportType.ToString();

            this.txtDatasetname.Text = _Datasetname;
            this.cbAddPrefix.Checked = _Prefix;
            this.cbShowInDebug.Checked = _DebugMode;
            this.cbSnapshot.Checked = _Snapshot;
            this.cbWindowsAuthorization.Checked = _WindowsAuthorization;
            this.txtUsername.Text = _Username;
            this.txtPassword.Text = _Password;

            //if (_Reportparameter != null)
            //{
            //    SetParameter(_Reportparameter);
            //}

            ///Set Filename Variables
            cbxPrefixFilename.BeginUpdate();

            //cbxPrefixFilename.Items.Add("Choose a Variable");
            AddVariableToRow("Choose a Variable");

            foreach (Variable var in _taskHost.Variables)
            {
                if (!var.ReadOnly)
                {
                    cbxPrefixFilename.Items.Add(var.QualifiedName);
                    AddVariableToRow(var.QualifiedName);
                }
            }

            if (_Reportparameter != null)
            {
                SetParameter(_Reportparameter);
            }
            
            //Set the selected variable
            if (_PrefixFilename != null)
            {
                cbxPrefixFilename.SelectedItem = _PrefixFilename;
            }

            cbxPrefixFilename.EndUpdate();

            ///Set Recordset Variables
            cbxRecordset.BeginUpdate();
                       
            foreach (Variable var in _taskHost.Variables)
            {
                if (!var.ReadOnly)
                {
                    cbxRecordset.Items.Add(var.QualifiedName);
                }
            }

            if (_Recordset != null)
            {
                cbxRecordset.SelectedItem = _Recordset;
            }



            cbxRecordset.EndUpdate();
            
            ChangeUI();
            //AddComboBoxColumns();
        }

        #endregion

        #region Control Event Handlers
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnOK_Click(object sender, EventArgs e)
        {
            System.IO.FileInfo FI = new System.IO.FileInfo(txtLocation.Text);
            if (!System.IO.Directory.Exists(FI.DirectoryName))
            {
                MessageBox.Show("The specified report folder does not exist.", "ReportGeneratorTask", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {

                try
                {
                    this._taskHost.Properties["Recordset"].SetValue(this._taskHost, cbxRecordset.SelectedItem.ToString());
                }
                catch
                {
                    this._taskHost.Properties["Recordset"].SetValue(this._taskHost, null);
                }

                try
                {
                    this._taskHost.Properties["PrefixFilename"].SetValue(this._taskHost, cbxPrefixFilename.SelectedItem.ToString());
                }
                catch
                {
                    this._taskHost.Properties["PrefixFilename"].SetValue(this._taskHost, null);
                }

                try
                {
                    _Param = ReportGenerator.SerializeObject(GetDataTable());
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                    _Param = null;
                }

                this._taskHost.Properties["Reportparameter"].SetValue(this._taskHost, _Param);
                this._taskHost.Properties["Reportname"].SetValue(this._taskHost, txtReports.Text);
                this._taskHost.Properties["Filename"].SetValue(this._taskHost, txtLocation.Text);
                this._taskHost.Properties["Datasetname"].SetValue(this._taskHost, txtDatasetname.Text);
                this._taskHost.Properties["Prefix"].SetValue(this._taskHost, cbAddPrefix.Checked);
                this._taskHost.Properties["DebugMode"].SetValue(this._taskHost, cbShowInDebug.Checked);
                this._taskHost.Properties["Snapshot"].SetValue(this._taskHost, cbSnapshot.Checked);
                this._taskHost.Properties["ReportType"].SetValue(this._taskHost, _ReportType);
                this._taskHost.Properties["ReportServer"].SetValue(this._taskHost, txtReportServer.Text);
                this._taskHost.Properties["Username"].SetValue(this._taskHost, txtUsername.Text);
                this._taskHost.Properties["Password"].SetValue(this._taskHost, txtPassword.Text);
                this._taskHost.Properties["WindowsAuthorization"].SetValue(this._taskHost, cbWindowsAuthorization.Checked);
                this.DialogResult = DialogResult.OK;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnReports_Click_1(object sender, EventArgs e)
        {
            if (_ReportType == "Dataset Report")
            {
                if (ofdReport.ShowDialog() == DialogResult.OK)
                {
                    this.txtReports.Text = ofdReport.FileName;
                    GetDataSet();
                }
            }
            else 
            {
                if (txtReportServer.Text != null)
                {
                    try
                    {
                        ReportServerUI frmReportServer = new ReportServerUI();
                        frmReportServer.Username = txtUsername.Text;
                        frmReportServer.Password = txtPassword.Text;
                        frmReportServer.WindowsAuthorization = cbWindowsAuthorization.Checked;
                        frmReportServer.Reportname = txtReports.Text;
                        frmReportServer.ReportServer = txtReportServer.Text;

                        if (frmReportServer.ShowDialog() == DialogResult.OK)
                        {
                            this.txtReports.Text = frmReportServer.Reportname;
                            GetReportParameter();
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("The report server could not be reached. Exception: " + ex.Message);
                    }
                }
                else
                {
                    MessageBox.Show("Please define a ReportServer");
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLocation_Click_1(object sender, EventArgs e)
        {
            // Always retrieve the Extensions again, because the report server can be changed!

            ReportExecution2005.ReportExecutionService rs = new ReportExecution2005.ReportExecutionService();
            rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
            rs.Url = txtReportServer.Text + "/ReportExecution2005.asmx";

            Extension[] extensions = null;
            // Retrieve a list of all renderingextensions. 
            extensions = rs.ListRenderingExtensions();

            if (extensions != null)
            {
                string filter = "";
                foreach (Extension extension in extensions)
                {
                    // only add supporter extensions
                    if (_renderExtensions.Contains(extension.Name))
                    {
                        RenderExtension supportedExtension = (RenderExtension)_renderExtensions[extension.Name];
                        //build filter like: Acrobat (*.pdf)|*.pdf|Microsoft Excel (*.xls)|*.xls
                        if (filter.Length > 0) filter += "|";
                        filter += supportedExtension.FullName + " (" + supportedExtension.Extension + ")|" + supportedExtension.Extension;
                    }
                }
                sfdReport.Filter = filter;
            }
            if (sfdReport.ShowDialog() == DialogResult.OK)
            {
                this.txtLocation.Text = sfdReport.FileName;
            }
        }

        #endregion

        #region UI Link

        /// <summary>
        /// open project homepage on codeplex when link is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void linkCodeplex_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://ReportGeneratorTask.codeplex.com");
        }

        /// <summary>
        /// open datenfabarik.com when link is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void linkDatenfabrik_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.datenfabrik.com");
        }

        /// <summary>
        /// open sssis-components.net  when link is clicked
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://www.ssis-components.net");
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbReportType_SelectedIndexChanged(object sender, EventArgs e)
        {
            _ReportType = cbReportType.SelectedItem.ToString();
            ChangeUI();
        }

        /// <summary>
        /// changes the ui when the task execution is change between and local and server report
        /// </summary>
        private void ChangeUI()
        {
            if (_ReportType == "Dataset Report")
            {
                lblRecordset.Text = "Variable:";
                lblDatasetname.Enabled = true;
                txtDatasetname.Enabled = true;
                cbSnapshot.Enabled = false;
                btnAction.Text = "Generate Object";
                //gbAuthorization.Enabled = false;
                cbxRecordset.Visible = true;
                txtReportServer.Visible = false;
                tabControl1.TabPages["tpParameter"].IsAccessible = false;
            }
            else 
            {
                lblRecordset.Text = "Reportserver:";
                lblDatasetname.Enabled = false;
                txtDatasetname.Enabled = false;
                cbSnapshot.Enabled = true;
                btnAction.Text = "Test Reportserver";
                //gbAuthorization.Enabled = true;
                cbxRecordset.Visible = false;
                txtReportServer.Visible = true;
                tabControl1.TabPages["tpParameter"].IsAccessible = true;
            }
        }

        /// <summary>
        /// enables the username and password textbox when windowsauthorizatuion check changed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbWindowsAuthorization_CheckedChanged(object sender, EventArgs e)
        {
            txtUsername.Enabled = !cbWindowsAuthorization.Checked;
            txtPassword.Enabled = !cbWindowsAuthorization.Checked;
        }

        /// <summary>
        /// enables the filename textbox when prefix is used
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbAddPrefix_CheckedChanged(object sender, EventArgs e)
        {
            cbxPrefixFilename.Enabled = cbAddPrefix.Checked;
        }

        /// <summary>
        /// get the dataset name from a local report
        /// </summary>
        private void GetDataSet()
        {
            try
            {  
                XmlDocument doc = new XmlDocument();
                doc.Load(txtReports.Text.ToString());
                XmlNodeList nl1 = doc.GetElementsByTagName("DataSet");
                txtDatasetname.Text = nl1.Item(0).Attributes.Item(0).Value.ToString();                                              
            }
            catch { }
        }

        /// <summary>
        /// Get parameters from the server report and set them to the datagrid.
        /// </summary>
        private void GetReportParameter()
        {
            try
            {
                ReportService2005.ReportingService2005 rs = new ReportService2005.ReportingService2005();
                rs.Credentials = System.Net.CredentialCache.DefaultCredentials;
                rs.Url = txtReportServer.Text + "/ReportService2005.asmx";
                ReportService2005.ReportParameter[] Param = rs.GetReportParameters(txtReports.Text, null, false, null, null);

                dgvReportParameter.Rows.Clear();
                
                for (int i = 0; i <= Param.Length - 1; i++)
                {
                    AddRow(Param[i].Name);
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show("When you retrieve the report parameter, an error has occurred: " + ex.Message);
            }
         }

        /// <summary>
        /// Add Report Parameter
        /// </summary>
        /// <param name="Parameter"></param>
        private void AddRow(string Parameter)
        {
            try
            {
                DataGridViewRow dgv = new DataGridViewRow();
                               
                DataGridViewComboBoxCell cbc = new DataGridViewComboBoxCell();
                cbc.DataSource = _Variable;
                cbc.ValueMember = "Variable";
                cbc.DisplayMember = "Variable";

                dgv.Cells.Add(cbc);

                DataGridViewTextBoxCell txt = new DataGridViewTextBoxCell();
                txt.Value = Parameter;

                dgv.Cells.Add(txt);

                this.dgvReportParameter.Rows.Add(dgv);
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Parameter"></param>
        /// <param name="Value"></param>
        private void AddRow(string Parameter, string Value)
        {
            try
            {
                DataGridViewRow dgv = new DataGridViewRow();
                               
                DataGridViewComboBoxCell cbc = new DataGridViewComboBoxCell();
                cbc.DataSource = _Variable;
                cbc.ValueMember = "Variable";
                cbc.DisplayMember = "Variable";
                
                foreach (DataRow row in _Variable.Rows)
                {
                    if (row["Variable"].ToString() == Value.ToString())
                    {
                        cbc.Value = Value;   
                    }
                }
                                
                dgv.Cells.Add(cbc);
                DataGridViewTextBoxCell txt = new DataGridViewTextBoxCell();
                txt.Value = Parameter;
                dgv.Cells.Add(txt);

                this.dgvReportParameter.Rows.Add(dgv);
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        /// <summary>
        /// Builds a datatable with one column
        /// </summary>
        private void BuildDataTable()
        {
            _Variable = new DataTable();
            _Variable.Columns.Add("Variable", System.Type.GetType("System.String"));
        }

        /// <summary>
        /// adds a package variable to the local datatable
        /// </summary>
        /// <param name="Variable"></param>
        private void AddVariableToRow(string Variable)
        {
            DataRow dr = _Variable.NewRow();
            dr["Variable"] = Variable;
            _Variable.Rows.Add(dr);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        private DataTable GetDataTable()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Variable");
            dt.Columns.Add("Parameter");
            foreach (DataGridViewRow row in dgvReportParameter.Rows)
            {
                DataRow r = dt.NewRow();
                r[0] = row.Cells[0].Value;
                r[1] = row.Cells[1].Value;
                dt.Rows.Add(r);
            }

            return dt;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        private void SetParameter(DataTable dt)
        {
            foreach(DataRow row in dt.Rows)
            {
                AddRow(row[1].ToString(), row[0].ToString());
            }
        }

     }
}
